#include "cocoa/auto.h"
#include "cocoa/caglcontext.h"
#include "cocoa/ccocoaautoreleasepool.h"

namespace buola { namespace gui { namespace cocoa {

CAGLContext *CAGLContext::mReferenceContext=nullptr;
//CX11Window *CAGLContext::mFakeWindow=nullptr;

static NSOpenGLPixelFormat *create_pixel_format(CCocoaWindow *pW)
{
    std::vector<NSOpenGLPixelFormatAttribute> lAttrs;

    lAttrs.push_back(NSOpenGLPFADoubleBuffer);

    lAttrs.push_back(NSOpenGLPFAOpenGLProfile);
    lAttrs.push_back(NSOpenGLProfileVersion3_2Core);
    lAttrs.push_back(NSOpenGLPFADepthSize);
    lAttrs.push_back(32);
    lAttrs.push_back(0);
///\todo
/*
    if (format.depthBufferSize() > 0)
        attrs <<  NSOpenGLPFADepthSize << format.depthBufferSize();
    if (format.stencilBufferSize() > 0)
        attrs << NSOpenGLPFAStencilSize << format.stencilBufferSize();
    if (format.alphaBufferSize() > 0)
        attrs << NSOpenGLPFAAlphaSize << format.alphaBufferSize();

    if (format.samples() > 0) {
        attrs << NSOpenGLPFAMultisample
              << NSOpenGLPFASampleBuffers << (NSOpenGLPixelFormatAttribute) 1
              << NSOpenGLPFASamples << (NSOpenGLPixelFormatAttribute) format.samples();
    }

    attrs << 0;
*/

    return [[NSOpenGLPixelFormat alloc] initWithAttributes:lAttrs.data()];
}

CAGLContext::CAGLContext(CCocoaWindow *pWindow)
    :   mWindow(pWindow)
{
    if(!mReferenceContext)
        mReferenceContext=new CAGLContext(nReferenceContext);

    CCocoaAutoReleasePool lPool; // For the SG Canvas render thread

    NSOpenGLPixelFormat *lPixelFormat=create_pixel_format(pWindow);
    
    mContext=[[NSOpenGLContext alloc] initWithFormat:lPixelFormat shareContext:mReferenceContext->mContext];
    [mContext setView:mWindow->ContentView()];
    
    if(!mContext)
        throw XInvalid("can't create OpenGL context");
        
    ///\todo find out what this means
//    const GLint interval = 1;
//    [m_context setValues:&interval forParameter:NSOpenGLCPSwapInterval];
}

CAGLContext::CAGLContext(NReferenceContext)
    :   mWindow(nullptr)
{
    NSOpenGLPixelFormat *lPixelFormat=create_pixel_format(nullptr);
    
//    mFakeWindow=new CX11Window(nullptr,get_default_x11_display());
//    mFakeWindow->CreateWindow(nullptr,CPoint_d(0,0),CSize_d(1,1),CWindow::ATTRIB_NONE,EVENT_NONE);
//    mSurface=mFakeWindow;

    mContext=[[NSOpenGLContext alloc] initWithFormat:lPixelFormat shareContext:nil];
}

CAGLContext::CAGLContext(NWithoutWindow)
{
    if(!mReferenceContext)
        mReferenceContext=new CAGLContext(nReferenceContext);

//    mSurface=mFakeWindow;
//    mInterface=INTERFACE_AGL(mSurface);

    NSOpenGLPixelFormat *lPixelFormat=create_pixel_format(nullptr);
    mContext=[[NSOpenGLContext alloc] initWithFormat:lPixelFormat shareContext:mReferenceContext->mContext];
}

CAGLContext::~CAGLContext()
{
///\todo check if there is really nothing to do
//    glXDestroyContext(get_default_x11_display()->GetDisplay(),mContext);
}

void CAGLContext::MakeCurrent(img::CSurface *pSurface)
{
    msg_info() << "making current\n";
    if(pSurface&&pSurface!=mWindow)
    {
        mWindow=throwing_cast<CCocoaWindow*>(pSurface);
        [mContext setView:mWindow->ContentView()];
    }
    
    [mContext makeCurrentContext];
    [mContext update];

}

bool CAGLContext::IsCurrent()
{
    return mContext==[NSOpenGLContext currentContext];
}

void CAGLContext::SwapBuffers()
{
    msg_info() << "flushing buffer\n";
    [mContext flushBuffer];
}

/*namespace cocoa*/ } /*namespace gui*/ } /*namespace buola*/ }
